package org.x.user.service.impl;


import cn.dev33.satoken.stp.StpUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import io.micrometer.common.util.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.x.common.config.BusinessException;
import org.x.user.dto.*;
import org.x.user.entity.SysRoleUserEntity;
import org.x.user.entity.SysUserEntity;
import org.x.user.mapper.SysUserMapper;
import org.x.user.service.ISysDeptService;
import org.x.user.entity.SysDeptEntity;
import org.x.user.mapper.SysDeptMapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.x.user.vo.DeptTreeVO;
import org.x.user.vo.DeptUserVO;
import org.x.user.vo.SysDeptVO;
import org.x.user.vo.SysUserVO;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 部门表 服务层实现。
 *
 * @author mybatis-flex-helper automatic generation
 * @since 1.0
 */
@Service
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDeptEntity> implements ISysDeptService {
    @Autowired
    private SysDeptMapper sysDeptMapper;
    @Autowired
    private SysUserMapper sysUserMapper;

    @Override
    public Long create(CreateDeptDTO createDeptDTO) {
        SysDeptEntity sysDept = new SysDeptEntity();
        BeanUtils.copyProperties(createDeptDTO, sysDept);
        sysDept.setIsDelete(0);
        sysDept.setCreatedTime(new Date());
        SysUserEntity sysUserEntity = sysUserMapper.selectOneById(StpUtil.getLoginIdAsLong());
        sysDept.setCreatedBy(sysUserEntity.getUsername());
        sysDept.setLevel(calculateLevelPath(createDeptDTO.getParentId(), sysDept.getId()));

        sysDeptMapper.insert(sysDept);

        return sysDept.getId();
    }

    // 计算部门路径
    public String calculateLevelPath(Long parentId, Long deptId) {
        if (parentId == 0) {
            return "1"; // 根部门路径
        }
        SysDeptEntity parent = sysDeptMapper.selectOneById(parentId);
        return parent.getLevel() + "." + deptId;
    }

    @Override
    public void update(UpdateDeptDTO updateDeptDTO) {
        SysDeptEntity sysDept = sysDeptMapper.selectOneById(updateDeptDTO.getDeptId());

        if (sysDept == null) {
            throw new BusinessException("部门不存在");
        }

        BeanUtils.copyProperties(updateDeptDTO, sysDept);
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq(SysDeptEntity::getId, updateDeptDTO.getDeptId());

        SysUserEntity sysUserEntity = sysUserMapper.selectOneById(StpUtil.getLoginIdAsLong());
        sysDept.setUpdatedBy(sysUserEntity.getUsername());
        sysDept.setUpdatedTime(new Date());

        sysDeptMapper.updateByQuery(sysDept, wrapper);
    }

    @Override
    public void deleteById(Long deptId) {
        SysDeptEntity sysDept = sysDeptMapper.selectOneById(deptId);

        if (deptId == 1){
            throw new BusinessException("根部门禁止删除");
        }
        if (sysDept == null) {
            throw new BusinessException("部门不存在");
        }
        if (sysDept.getIsDelete() == 1) {
            throw new BusinessException("部门已删除");
        }
        //部门下存在用户时禁止删除
        if (sysUserMapper.selectCountByQuery(new QueryWrapper().eq(SysUserEntity::getDeptId, deptId)) > 0) {
            throw new BusinessException("部门下存在用户，禁止删除");
        }

        //实现级联删除
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.like(SysDeptEntity::getLevel, sysDept.getLevel() + "%");

        SysDeptEntity updateEntity = new SysDeptEntity();
        updateEntity.setIsDelete(1);

        sysDeptMapper.updateByQuery(updateEntity, queryWrapper);
    }


    @Override
    public Page<SysDeptVO> list(DeptQueryDTO deptQueryDTO) {
        //判断deptQueryDTO中的值是否为null.不为null的才构建查询条件
        QueryWrapper queryWrapper = new QueryWrapper();
        if (!StringUtils.isEmpty(deptQueryDTO.getName())) {
            queryWrapper.like(SysDeptEntity::getName, deptQueryDTO.getName());
        }
        //构建分页条件(page,size)
        Page<SysDeptEntity> paginate = sysDeptMapper.paginate(deptQueryDTO.getPage(), deptQueryDTO.getSize(), queryWrapper);
        //获取分页结果中的数据
        List<SysDeptEntity> records = paginate.getRecords();

        //构建VO
        Page<SysDeptVO> page = new Page<>();
        List<SysDeptVO> list = new LinkedList<>();
        records.forEach(record -> {
            SysDeptVO sysDeptVO = new SysDeptVO();
            BeanUtils.copyProperties(record, sysDeptVO);
            list.add(sysDeptVO);
        });
        page.setRecords(list);
        page.setTotalRow(paginate.getTotalRow());
        page.setTotalPage(paginate.getTotalPage());
        page.setPageNumber(paginate.getPageNumber());
        page.setPageSize(paginate.getPageSize());

        return page;
    }

    @Override
    public SysDeptEntity detail(Long deptId) {
        if (deptId == null) {
            throw new BusinessException("部门id不能为空");
        }
        SysDeptEntity sysDept = sysDeptMapper.selectOneById(deptId);
        if (sysDept == null) {
            throw new BusinessException("部门不存在");
        }
        return sysDept;
    }

    //树形结构算法
    public List<DeptTreeVO> buildDeptTree(List<SysDeptEntity> deptList) {
        Map<Long, DeptTreeVO> treeMap = new HashMap<>();
        List<DeptTreeVO> roots = new ArrayList<>();

        // 创建所有节点
        for (SysDeptEntity dept : deptList) {
            DeptTreeVO tree = convertToTreeVO(dept);
            treeMap.put(dept.getId(), tree);

            if (dept.getParentId() == null || dept.getParentId() == 0) {
                roots.add(tree);
            }
        }

        // 构建树结构
        for (SysDeptEntity dept : deptList) {
            if (dept.getParentId() != null && dept.getParentId() != 0) {
                DeptTreeVO parent = treeMap.get(dept.getParentId());
                if (parent != null) {
                    parent.addChild(treeMap.get(dept.getId()));
                }
            }
        }

        // 按sort排序
        roots.sort(Comparator.comparingInt(DeptTreeVO::getSort));
        return roots;
    }

    private DeptTreeVO convertToTreeVO(SysDeptEntity dept) {
        DeptTreeVO treeVO = new DeptTreeVO();
        treeVO.setId(dept.getId());
        treeVO.setName(dept.getName());
        treeVO.setParentId(dept.getParentId());
        treeVO.setSort(dept.getSort());
        return treeVO;
    }

    @Override
    public List<DeptTreeVO> tree() {
        List<SysDeptEntity> deptList = sysDeptMapper.selectAll();
        List<DeptTreeVO> treeVOList = this.buildDeptTree(deptList);

        return treeVOList;
    }

    @Override
    public DeptUserVO userList(DeptUserDTO deptUserDTO) {
        //检验部门存在性
        SysDeptEntity dept = sysDeptMapper.selectOneById(deptUserDTO.getDeptId());
        if (dept == null) {
            throw new BusinessException("部门不存在");
        }

        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq(SysUserEntity::getDeptId, deptUserDTO.getDeptId());
        Page<SysUserEntity> paginate = sysUserMapper.paginate(deptUserDTO.getPage(), deptUserDTO.getSize(), wrapper);

        List<SysUserEntity> records = paginate.getRecords();
        // 转换成VO
        List<DeptUserVO.User> users = records.stream().map(item -> {
            DeptUserVO.User user = new DeptUserVO.User();
            BeanUtils.copyProperties(item, user);
            return user;
        }).toList();
        DeptUserVO deptUserVO = new DeptUserVO();
        deptUserVO.setTotal(paginate.getTotalRow());
        deptUserVO.setRecords(users);

        return deptUserVO;
    }

    @Transactional
    @Override
    public void structure(List<DeptStructureDTO> changes) {
        if (changes == null || changes.isEmpty()) {
            return;
        }

        for (DeptStructureDTO change : changes) {
            // 检查部门ID是否为空
            if (change.getDeptId() == null) {
                throw new BusinessException("部门ID不能为空");
            }

            SysDeptEntity dept = sysDeptMapper.selectOneById(change.getDeptId());
            // 添加对dept的空值检查
            if (dept == null) {
                throw new BusinessException("部门不存在，部门ID: " + change.getDeptId());
            }

            // 检查parentId是否为空
            if (change.getParentId() == null) {
                throw new BusinessException("父部门ID不能为空");
            }

            // 防止将部门设置为自己的父部门
            if (change.getDeptId().equals(change.getParentId())) {
                throw new BusinessException("不能将部门设置为自己的父部门");
            }

            dept.setParentId(change.getParentId());

            checkParentChange(change.getDeptId(), change.getParentId());

            dept.setSort(change.getSort());
            sysDeptMapper.update(dept);
        }
        rebuildAllLevelPaths(); // 重建所有层级路径
    }


    // 重建所有层级路径
    public void rebuildAllLevelPaths() {
        // 获取所有部门
        List<SysDeptEntity> allDepts = sysDeptMapper.selectAll();
        Map<Long, SysDeptEntity> deptMap = allDepts.stream()
                .collect(Collectors.toMap(SysDeptEntity::getId, d -> d));

        // 重建层级路径
        for (SysDeptEntity dept : allDepts) {
            // 添加对parentId的空值检查
            if (dept.getParentId() == null || dept.getParentId() == 0) {
                dept.setLevel("1");
            } else {
                SysDeptEntity parent = deptMap.get(dept.getParentId());
                if (parent != null) {
                    dept.setLevel(parent.getLevel() + "." + dept.getId());
                } else {
                    // 如果父部门不存在，则将该部门视为根部门
                    dept.setLevel("1");
                }
            }
            sysDeptMapper.update(dept);
        }
    }

    public void checkParentChange(Long deptId, Long newParentId) {
        if (newParentId == 0) return;

        // 获取新父部门的层级路径
        SysDeptEntity newParent = sysDeptMapper.selectOneById(newParentId);
        if (newParent.getLevel().contains("." + deptId + ".")) {
            throw new BusinessException("不能将部门转移到子部门下");
        }
    }
}